{% extends "frame.html" %}

{% block title %}{{ user.name }}({{ user.screen_name }}) / GTW(GAETwitter){% endblock title %}

{% block main %}
    <div class="user_title">
        <img title="{{ user.screen_name }}" src="{{ user.profile_image_url }}" />
        <h2>{{ user.screen_name }}</h2>
    </div>
    <div class="user_controls round">
        {% if user.following %}
    	<div class="isfollowing">Following</div>
    	{% endif %}
    	<div class="controls">
    	    {% if user.following %}
	    	<a href="#" title="Unfollow" class="unfollow"><i></i>Unfollow</a>
	    	{% else %}
	    	<a href="#" title="Follow" class="follow"><i></i>Follow</a>
	    	{% endif %}
	    	<a href="#" title="Mention" class="mention"><i></i>Mention</a>
	    	<a href="#" title="Block" class="block"><i></i>Block</a>
	    	{% if user.following %}
	    	<a href="#" title="Direct message" class="message"><i></i>Direct message</a>
	    	{% endif %}
	    	<a href="#" title="Report spam" class="spam"><i></i>Report spam</a>
    	</div>
    </div>
    <h3 class="home">Tweets: <a id="retrieve_link" href="/" title="Retrieve new tweets"><b>&nbsp;</b>Retrieve new tweets</a><span id="retrieving" class="loading">Retrieving new tweets...</span></h3>
    <div>
    	<a id="results_update" style="display:none;" accesskey="n" href="/" class="notifier"></a>
    </div>
    <ol id="statuses_box" class="statuses">
    	<li id="status_">Retrieving new tweets...</li>
    </ol>
    <a href="/{{ user.screen_name }}/tweets" style="visibility:hidden" class="more round">newer</a>
    <a href="/{{ user.screen_name }}/tweets/2" class="more round">older</a>
{% endblock main %}

{% block profile %}
<div class="profile">
	<ul class="detail">
		<li><b>Name</b>{{ user.name }}</li>
		<li><b>Location</b>{{ user.location }}</li>
		<li><b>Web</b><a href="{{ user.url }}" title="">{{ user.url }}</a></li>
		<li><b>Bio</b>{{ user.description }}</li>
	</ul>
    <ul class="stats">
        <li>{{ user.friends_count }}<a href="/{{ user.screen_name }}/friends/">following</a></li>
        <li>{{ user.followers_count }}<a href="/{{ user.screen_name }}/follwers/">followers</a></li>
        <li>/<a href="/{{ user.screen_name }}/lists/memberships">listed</a></li>
    </ul>
</div>
{% endblock profile %}

{% block user_ralated %}
<ul class="side_nav">
    <li><a class="current" href="/{{ user.screen_name }}" title="">Tweets ({{ user.statuses_count }})</a></li>
    <li><a href="/{{ user.screen_name }}/favorites" title="">Favorites</a></li>
</ul>
{% endblock user_ralated %}

{% block scripts %}
<div id="confirm_tips" class="confirm_tips">
	<div class="confirm_box">
		<div class="msg"></div>
		<a href="javascript:;" class="cancel"> </a>
		<a href="javascript:;" class="yes">Yes</a>
	</div>
</div>
<script type="text/javascript">
// output by server
var screen_name = '{{ user.screen_name }}';
// end of server outputs

// datetime tools
var dateTime = {
		parseGMT: function(str){
		    var months = {'Jan': 0, 'Feb': 1, 'Mar': 2, 'Apr': 3, 'May': 4, 'Jun': 5, 'Jul': 6, 'Aug': 7, 'Sep': 8, 'Oct': 9, 'Nov': 10, 'Dec': 11},
		        time = new Date(str);
		    if(time == 'NaN'){
		    	var ds = str.split(' '), ts = ds[3].split(':');
		    	time = new Date(ds[5], months[ds[1]], ds[2], ts[0], ts[1], ts[2]);
		    	time = new Date(time.getTime() + new Date(-new Date().getTimezoneOffset() * 60 * 1000).getTime());
		    }
		    return time;
		},
		semantic: function(time){
			time = dateTime.parseGMT(time);
			var diff = Math.round((new Date() - time) / 1000),
			    ticks = [3600 * 24, 3600, 60],
			    ret = '';
			if(diff > ticks[0]){
				ret = [time.getFullYear(), '-', time.getMonth(), '-', time.getDate(), ' ', time.getHours(), ':', time.getMinutes()].join('');
			}
			else{
				var h = Math.floor(diff / ticks[1]), 
				    m = Math.floor((diff % ticks[1]) / ticks[2]),
				    s = diff % ticks[2];

			    if(h > 0){
			    	ret = (h > 1 ? ('about ' + h + ' hours ') : 'less than a hour ') + 'ago';
			    }
			    else if(m > 0){
			    	ret = (m > 1 ? ('about ' + m + ' minutes ') : 'less than a minute ') + 'ago';
			    }
			    else if(s > 0){
			    	ret = (s > 1 ? ('about ' + s + ' seconds ') : 'less than a second ') + 'ago';
			    }
			    else{
			    	ret = 'just now'
			    }
			}
			return ret;
		}
};

// confirm toolbar
var confirmTips = (function(box){
	var cb = $.empty, ref = null;
	function clickHandler(evt, flag){
		evt.stop();
		box.css('display', 'none');
		cb.apply(ref, [flag]);
	}
	var actions = {
			yes: function(evt){
					clickHandler(evt, true);
				},
			cancel: function(evt){
					clickHandler(evt, false);
				}
		};
	var msgbox = box.getElement('div.msg'), btns = box.getElements('a'), i = 0, btn;
	while(btn = btns[i++]){
		btn.addEvent('click', actions[btn.className])
	}
	
	function show(rel, msg, callback, bind){
		if(!rel) return;

		cb = callback;
		ref = bind;

		msgbox.innerHTML = msg;
		box.css('display', 'block');
		var pos = rel.position(),
		    size = rel.dimension();

	    pos.x = pos.x + (size.width >> 1);
	    pos.y = pos.y + size.height;
		box.css({'left': (pos.x - 264) + 'px', 'top': pos.y + 'px'});
	}
	return {
		show: show
	};
})($('#confirm_tips'));

// page controller
var home = (function () {
    var updateInterval = 60 * 1000,
    since_id = 0,
    max_id = 0,
    timer = 0,
    inited = false,
    newsCount = 0,
    maxShow = 50,
    relatedId = false,
    cur_page = 1,

    // find related doms
    box = $('#statuses_box'),
    retrieve = $('#retrieve_link'),
    loading = $('#retrieving'),
    notifier = $('#results_update'),
    status_text = $('textarea[name=status]')[0],
    reply_to = $('input[name=reply_to]')[0],
    tweet_btn = $('#post_tweet'),

    // fragment to store new tweets
    frag = document.createDocumentFragment(),

    // only one request on a page
    // when send a new request, it will cancel the last one
    request = new $.Ajax({link:'cancel', cache:true});

    // bind events
    retrieve && retrieve.addEvent('click', forceRetrieve);
    notifier && notifier.addEvent('click', showNewTweets);
    
    function forceRetrieve(evt){
        evt.stop();
        update();
    }
    
    function showNewTweets(evt){
        evt && evt.stop();
        this.blur();
        box.prepend(frag);
        newsCount = 0;
        frag = document.createDocumentFragment();
        
        notifier.css('display', 'none');
        box.css('border-top-width', '1px');
        document.title = document.title.replace(/\(\d+\)/, '');

        var lis = box.getElements('li'), li, i = 0, a;
        while(li = lis[i++]){
            if(i >= maxShow){
                li.destroy();
            }
            else{
                a = li.getElement('a.entry-date');
                a.innerHTML = dateTime.semantic(a.attr('time'));
                max_id = parseInt(li.id.split('_')[1], 10);
            }
        }
    }

    function doReply(evt){
        evt.stop();
        status_text.value = '@' + $('#status_' + this.cache('sid')).getElement('span b').txt() + ' ';
        reply_to.value = this.cache('sid');
        status_text.focus();
    }

    function doRetweet(evt){
        evt.stop();
        status_text.value = $('#status_' + this.cache('sid')).getElements('span')[1].innerHTML.replace(/<b.*?<a.*?>(.*?)<\/a>.*?<\/b>/img, 'RT @$1: ').replace(/<span.*$/ig, '').replace(/(<.*?>)|(^\s+)|(\s+$)/ig, '');
        status_text.focus();
    }

    function doNewRetweet(evt){
        evt.stop();
        relatedId = this.cache('sid');
        confirmTips.show(this, 'Retweet to your followers?', home.newRetweet);
    }

    function doFavorite(evt){
        evt.stop();
    	clearTimeout(timer);
    	relatedId = this.cache('sid');
        var url = '/home?do=favorite&action=create&id=' + relatedId;
        if(this.className == 'star'){
        	url = '/home?do=favorite&action=destroy&id=' + relatedId;
        }
        request.json({url: url, data:{}, onSuccess: favoriteSuccess, onEnd: actionLoaded, method: 'get'});
    }

    function doDelete(evt){
        evt.stop();
        relatedId = this.cache('sid');
        confirmTips.show(this, 'Sure to delete this tweet?', home.deleteTweet);
    }

    function deleteTweet(flag){
        if(!flag){
            return;
        }
    	clearTimeout(timer);
        var url = '/home?do=destroy&id=' + relatedId;
        request.json({url: url, data:{}, onSuccess: deleteSuccess, onEnd: actionLoaded, method: 'get'});
    }

    function newRetweet(flag){
        if(!flag){
        	return;
        }
    	clearTimeout(timer);
        var url = '/home?do=retweet&id=' + relatedId;
        request.json({url: url, data:{}, onSuccess: retweetSuccess, onEnd: actionLoaded, method: 'get'});
    }

    function actionLoaded(){
    	clearTimeout(timer);
        timer = setTimeout(update, updateInterval);
        return;
    }

    function favoriteSuccess(data){
        if(data.favorited){
            $('#status_' + relatedId + ' .favorite')[0].className = 'star';
        }
        else{
            $('#status_' + relatedId + ' .star')[0].className = 'favorite';
        }
    }

    function deleteSuccess(data){
        $('#status_' + relatedId).destroy();
        return;
    }

    function retweetSuccess(data){
        if(data.retweeted_status){
            update();
        }
        return;
    }
    
    function success(data) {
        if(!data){
            return;
        }
        if(since_id >= data.since_id){
            return;
        }

        since_id = data.since_id;  
        var div = new $.Element('div');      
        div.innerHTML = data.html;

        var action = {
                'reply': doReply,
                'retweet': doRetweet,
                'new_retweet': doNewRetweet,
                'favorite': doFavorite,
                'star': doFavorite,
                'delete': doDelete
            };

        // process html
        var lis = $(div.getElementsByTagName('li')), i = 0, li, 
            btns, j = 0, btn, id, fc = null, method,
            merge = {
                before: function(li, rel){
            		frag.insertBefore(li, rel);
            	},
                after: function(li){
                    frag.appendChild(li);
                }
            };

        method = merge.after;
        if(newsCount){
            fc = frag.firstChild;
            method = merge.before;
        }

        while(li = lis[i++]){
            id = li.id.split('_')[1];
            btns = li.getElements('.action a');
            j = 0;
            while(btn = btns[j++]){
                btn.cache('sid', id);
                btn.addEvent('click', action[btn.className]);
            }
            method(li, fc);
        }
        newsCount += (i - 1);
        notifier.innerHTML = newsCount + ' new tweet' + (i > 1 ? 's' : '');
        document.title = document.title.replace(/^(\(\d+\))?/, '(' + newsCount + ')');
        notifier.css('display', 'block');
        box.css('border-top-width', '0');
        
        if(!inited || screen_name !== false){
            box.innerHTML = '';
            inited = true;
            showNewTweets();
        }
    }

    function loaded(){
        if(screen_name === false){
        	timer = setTimeout(update, updateInterval);
        }
        loading.css('display', 'none');
        retrieve.css('display', 'inline');
        return;
    }

    function update(page) {
    	clearTimeout(timer);
        loading.css('display', 'inline');
        retrieve.css('display', 'none');
        // since_id and page cannot appear at the same time
        var url = '/home?do=home_timeline&since_id=' + (since_id || '');
        if(screen_name !== false){
        	url = ['/home?do=timeline&screen_name=', screen_name, '&page=', page || 1].join('');
        }
        else if(page){
            url = '/home?do=timeline&page=' + page;
        }
        request.json({url: url, data:{}, onSuccess: success, onEnd: loaded});
    }

    if(tweet_btn){
	    tweet_btn.addEvent('click', function(evt){
	    	evt.stop();
	    	var url = '/home?do=update',
	    	    data = {};
	
	    	data['status'] = status_text.value.replace(/(^\s+)|(\s+$)/g, '');
	    	data['reply_to'] = reply_to.value;
	
	    	if(data['status'] == ''){
	    		return;
	    	}
	
	    	tweet_btn.disabled = true;
	    	tweet_btn.className = 'disabled';
	        function success(data) {
	        	status_text.value = '';
	        	setTimeout(home.update, 100);
	    	    return;
	        }
	    	    
	        function loaded(){
	        	tweet_btn.className = 'active';
	        	tweet_btn.disabled = false;
	            return;
	        }
	    	request.text({url: url, data: data, onSuccess: success, onEnd: loaded, method: 'post'});
	    });
    }

    if(screen_name !== false){
    	update(1);
    }
    else{
        update();
    }

    return {
        update: update,
        newRetweet: newRetweet,
        deleteTweet: deleteTweet
    };
})();
</script>
{% endblock scripts %}